Amazon RDS for PostgreSQLのレプリケーションとフェイルオーバーの仕様を確認してみた
はじめに
大阪オフィス オペレーション部 瀬田です。 DBを運用する上で避けては通れないレプリケーションとフェイルオーバーですが、RDSの動作を公式ドキュメントを参考に確認して行こうと思います。 なお、対象はPostgreSQL10となります。
フェイルオーバー
まず、RDSの構成をみてみましょう。
S3にスナップショットとトランザクションログを保存し、 更新系はプライマリ1台に集約。セカンダリにフェイルオーバーする構成です。 S3のトランザクションログを利用して5分前でのPoint In Time Recoveryを実現しています。
レプリケーション(Multi-AZ)
フェイルオーバーが可能とわかると、気になってくるのはレプリケーションの動作。 障害時の切り替わりでデータ整合性を担保できるのかどうかドキュメントを確認してみます。
AWS公式ドキュメント マルチ AZ 配置とリードレプリカより
Multi-AZ 配備は、同期レプリケーションを活用して、データベースへの書き込みをプライマリとセカンダリで同時に行い、フェイルオーバーが発生した場合にスタンバイが最新の状態を保つようにしています。
同期レプリケーションはスタンバイへの書き込み確定後に応答するため、データ整合性を担保することができます。 このレプリケーションはミドルウエアより低レイヤーのレプリケーションで構成されており、 各DBエンジンの持つレプリケーション機能は使用されていません。 これにより高速なレプリケーションを実現しています。
レプリケーション(リードレプリカ)
ユースケースとして、スタンバイ側を読み込み専用機とし、プライマリの負荷を分散する構成にしたいことがあります。 しかし、スタンバイ側にはアクセスできない制限があります。
AWS公式ドキュメント マルチ AZ 配置とリードレプリカより
Multi-AZ DB インスタンスに対する当社の技術革新により障害発生時のデータ耐久性を最大化したことで、スタンバイに直接アクセスしたり、読み込み操作に使用されなくなりました。
代替機能としてDB インスタンス1つに対して、5つまでのリードレプリカ用のインスタンスを作成することができます。
読み込み負荷の高いデータベースワークロードに単一 DB インスタンスの能力が対応しきれない場合にキャパシティーの制約を超えてスケールするように、Amazon RDS にはリードレプリカが用意されています。
気をつけたいのは、リードレプリカは非同期レプリケーションであるということです。 プライマリからリードレプリカへのデータ伝播は非同期なので、リードレプリカのデータが最新であるとは限らず、プライマリの障害発生時にはプライマリとリードレプリカのデータの一貫性は担保されません。
マルチ AZ 配置とは異なり、これらのエンジンのリードレプリカは、各エンジンに組み込まれているレプリケーションテクノロジーを使いますが、これには、その長所と制限が反映されます。特に、更新は、ソース DB インスタンスに更新した後にリードレプリカに反映されるため ("非同期" レプリケーション)、レプリケーションラグは大幅に異なる場合があります。
この辺りは要件次第といったところですね。 素のPostgreSQL10はクォーラムコミットに対応しており、リードレプリカのデータの一貫性と可用性のバランスを取ることができますが、 RDSでは未対応となっています。今後の対応に期待したいと思います。
ロジカルレプリケーション
標準ではロジカルレプリケーションが動作していませんが、有効化することができます。 AWS Database Migration Serviceの使用等でロジカルレプリケーションが必要な場合はパラメータグループのrds.logical_replicationを有効化することで動作可能です。
リードレプリカ使用時のWALキャパシティ
リードレプリカはPostgreSQLのレプリケーションを使うため、WALのキャパシティ設計が素のPostgreSQLと同様に必要になります。
同一リージョンの注意点
wal_keep_segmentsの設定値分のファイル数でWALファイルがローテートするため、 リードレプリカに送信されるはずだった更新内容が消失することになり、レプリケーションは遅延、停止します。 これを防ぐために、十分なwal_keep_segmentsの大きさが必要となります。
AWS公式ドキュメント PostgreSQL リードレプリカでのレプリケーションの中断
データをリードレプリカに提供するために保持する WAL ファイルの数は、PostgreSQL パラメータ、wal_keep_segments で指定します。 パラメータ値は、保持するログの数を指定します。パラメータ値の設定が低すぎると、リードレプリカでのストリーミングに大幅な遅延が発生し、レプリケーションが停止します。
※参考
AWS公式ドキュメント Amazon RDS DB インスタンスでのストレージ不足時に発生する問題を解決する方法を教えてください。
必要な容量の確認
システムで使用されるWALの数を算出するには以下のようにログを確認することで可能です。 更新系の多いシステムは、余裕を持ったwal_keep_segmentsの個数を確保したいところです。
AWS公式ドキュメント PostgreSQL リードレプリカに関する問題のトラブルシューティングより
保持する WAL ファイルの数を決めるには、ログ内のチェックポイント情報を確認します。PostgreSQL ログの各チェックポイントに次の情報が示されます。これらログステートメントの "# recycled" トランザクションログファイルを確認することで、時間範囲内にリサイクルされるトランザクションファイルの数を把握し、またこの情報を使用して wal_keep_segments パラメータを調整できます。
監視によるアラート発報
ストレージの空き容量やWALの生成数を監視することで、事前に障害を検知することが可能です。 事前に検知できれば、インスタンスへのディスク追加や、リードレプリカの切り離しで対応することができます。 監視は必ず設定しておきたいですね。
※参考
AWS公式ドキュメント Amazon RDS のモニタリング
まとめ
大掛かりになりがちな冗長構成をRDSでは数分で構築することができるのはまさに福音といった感じです。 また 特性を理解して使えば、マネージドサービスの恩恵により浮いた時間でサービスレベルの向上に時間を割くことができ、より素晴らしいDBAライフが送れそうです。